package com.atguigu.tingshu.user.service.impl;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.RandomUtil;
import com.atguigu.tingshu.account.client.UserAccountFeignClient;
import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.common.result.Result;
import com.atguigu.tingshu.common.result.ResultCodeEnum;
import com.atguigu.tingshu.common.util.AuthContextHolder;
import com.atguigu.tingshu.model.user.UserInfo;
import com.atguigu.tingshu.user.service.UserInfoService;
import com.atguigu.tingshu.user.service.WxLoginService;
import com.atguigu.tingshu.vo.user.UserInfoVo;
import com.baomidou.mybatisplus.extension.toolkit.Db;
import io.seata.spring.annotation.GlobalTransactional;
import me.chanjar.weixin.common.error.WxErrorException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
public class WxLoginServiceImpl implements WxLoginService {

    @Autowired
    private WxMaService wxMaService;

    @Autowired
    private UserAccountFeignClient userAccountFeignClient;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private UserInfoService userInfoService;

    @Override
    @GlobalTransactional
    public Map<String, String> wxLogin(String code) {
        WxMaJscode2SessionResult sessionResult = null;
        try {
            // 获取openId
            sessionResult = wxMaService.getUserService().getSessionInfo(code);
            String openid = sessionResult.getOpenid();
            UserInfo userInfo = Db.lambdaQuery(UserInfo.class).eq(UserInfo::getWxOpenId, openid).one();
            // 如果用户不存在，则注册用户
            if (userInfo == null) {
                userInfo = new UserInfo();
                userInfo.setNickname("小猫耳" + RandomUtil.randomString(8));
                userInfo.setAvatarUrl("https://oss.aliyuncs.com/aliyun_id_photo_bucket/default_handsome.jpg");
                userInfo.setWxOpenId(openid);
                Db.save(userInfo);
                // 初始化账户信息
                Result result = userAccountFeignClient.initUserAccount(userInfo.getId());
                Assert.equals(result, Result.ok());
            }
            // 创建token
            UserInfoVo userInfoVo = BeanUtil.copyProperties(userInfo, UserInfoVo.class);
            String token = UUID.fastUUID().toString();
            redisTemplate.opsForValue().set(RedisConstant.USER_LOGIN_KEY_PREFIX + token,
                    userInfoVo,
                    RedisConstant.USER_LOGIN_KEY_TIMEOUT,
                    TimeUnit.SECONDS);
            Map<String, String> map = new HashMap<>();
            map.put("token", token);
            return map;
        } catch (WxErrorException e) {
            e.printStackTrace();
            throw new GuiguException(ResultCodeEnum.LOGIN_ERROR);
        }
    }

    @Override
    public UserInfoVo getUserInfo() {
        Long userId = AuthContextHolder.getUserId();
        UserInfo userInfo = userInfoService.getById(userId);
        UserInfoVo userInfoVo = BeanUtil.copyProperties(userInfo, UserInfoVo.class);
        return userInfoVo;
    }

    @Override
    public void updateUser(UserInfoVo userInfoVo) {
        UserInfo userInfo = BeanUtil.copyProperties(userInfoVo, UserInfo.class);
        userInfo.setId(AuthContextHolder.getUserId());
        userInfoService.updateById(userInfo);
    }
}
